package config

import (
	"context"
	"gitee.com/bobo-rs/creative-framework/pkg/sredis"
	"gitee.com/bobo-rs/innovideo-services/consts"
	"gitee.com/bobo-rs/innovideo-services/framework/dao"
	"gitee.com/bobo-rs/innovideo-services/framework/model"
	"gitee.com/bobo-rs/innovideo-services/library/tools"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"time"
)

// GetVar 读取业务配置
// 获取后台配置业务配置，例如：系统设置，基础配置，短信配置，第三方授权配置，支付配置等
// Example：
// New().GetVar(ctx, `basic`, `keywords`) // 配置名+配置组模式：获取基础配置类型下，关键词配置
// New().GetVar(ctx, `keywords`) // 配置名模式：直接获取关键词配置（注：确保配置名唯一）
func (c *sConfig) GetVar(ctx context.Context, names ...string) (*g.Var, error) {
	if len(names) == 0 {
		return nil, gerror.New(`配置名不能为空`)
	}
	var (
		where    = g.Map{}
		cacheKey = tools.CacheKey(consts.SysConfigKey, names...)
		item     model.ConfigNameValueItem
	)

	// 缓存配置
	return sredis.NewCache().GetOrSetFunc(ctx, cacheKey, func(ctx context.Context) (value interface{}, err error) {
		// 配置名和配置组名
		switch len(names) {
		case 1:
			// 根据配置名直接获取配置[确保配置名唯一]
			where[dao.Config.Columns().Name] = names[0]
		default:
			// 大于1，配置组+配置名
			where[dao.Config.Columns().Name] = names[0]
			where[dao.Config.Columns().GroupName] = names[1]
		}
		// 获取配置
		err = c.ProcessConfigScan(ctx, where, &item)
		if err != nil {
			return nil, err
		}
		// 配置值为空，读取默认值
		if len(item.Value) == 0 {
			return item.DefaultValue, nil
		}
		return item.Value, nil
	}, time.Hour)
}

// GetGroupVar 获取业务配置组
// 获取业务后台配置的配置组，例如：基础配置，短信配置，支付配置等
// Example：
// New().GetGroupVar(ctx, `basic`) // 获取所有基础配置
// New().GetGroupVar(ctx, `sms_tencent`) // 腾讯短信配置
// Output：&{`appid`:`xxxx`, `secret`:`xxxx`....}
func (c *sConfig) GetGroupVar(ctx context.Context, groupName string) (*g.Var, error) {
	if len(groupName) == 0 {
		return nil, gerror.New(`请输入业务配置组名，例如：basic基础配置`)
	}
	// 初始化
	var (
		cacheKey = tools.CacheKey(consts.SysConfigKey, groupName)
	)

	// 读取缓存
	return sredis.NewCache().GetOrSetFunc(ctx, cacheKey, func(ctx context.Context) (value interface{}, err error) {
		rawGroupMap, err := c.ProcessConfigMapByGroup(ctx, groupName)
		if err != nil {
			return nil, err
		}
		// 格式处理数据
		groupMap := make(map[string]interface{})
		for _, item := range rawGroupMap {
			groupMap[item.Name] = item.Value
		}
		return groupMap, nil
	}, time.Hour)

}

// MustGetGroupVar 获取配置组
func (c *sConfig) MustGetGroupVar(ctx context.Context, groupName string) *g.Var {
	// 读取配置组
	r, err := c.GetGroupVar(ctx, groupName)
	if err != nil {
		g.Log().Errorf(ctx, `获取业务配置组%s失败%s`, groupName, err)
		return nil
	}
	return r
}

// MustGetVar 获取业务配置Var类型
func (c *sConfig) MustGetVar(ctx context.Context, names ...string) *g.Var {
	// 读取配置
	r, err := c.GetVar(ctx, names...)
	if err != nil {
		g.Log().Errorf(ctx, `读取业务配置%+v失败%s`, names, err.Error())
		return nil
	}
	return r
}

// String 获取配置强制转换String类型
func (c *sConfig) String(ctx context.Context, names ...string) string {
	// 读取配置
	r := c.MustGetVar(ctx, names...)
	if r == nil {
		return ""
	}
	return r.String()
}

// Uint 获取配置值并强制为Uint类型
func (c *sConfig) Uint(ctx context.Context, names ...string) uint {
	// 读取配置
	r := c.MustGetVar(ctx, names...)
	if r == nil {
		return 0
	}
	return r.Uint()
}

// Int 配置内容强制转换为Int类型
func (c *sConfig) Int(ctx context.Context, names ...string) int {
	// 读取配置
	r := c.MustGetVar(ctx, names...)
	if r == nil {
		return 0
	}
	return r.Int()
}

// Map 获取配置组并转换为Map类型
func (c *sConfig) Map(ctx context.Context, groupName string) map[string]interface{} {
	// 读取配置
	r := c.MustGetGroupVar(ctx, groupName)
	if r == nil {
		return nil
	}
	return r.Map()
}
